home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / pbmplus / libtiff / mkg3states.c < prev    next >
C/C++ Source or Header  |  1995-06-14  |  25KB  |  814 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/mkg3states.c,v 1.16 93/08/25 09:08:33 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * Program to construct Group 3 & Group 4 decoding tables.
  31.  *
  32.  * This code is derived from code by Michael P. Marking.  In
  33.  * particular, the algorithms to generate the null_mode and
  34.  * horiz_mode state tables are his.  See the comments below
  35.  * for more information.
  36.  *
  37.  * BEGIN (from the original source)
  38.  LEGAL
  39.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  40.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  41.  *
  42.  *    License is granted by the copyright holder to distribute and use this
  43.  *    code without payment of royalties or the necessity of notification as
  44.  *    long as this notice (all the text under "LEGAL") is included.
  45.  *
  46.  *    Reference: $Id: mkg3states.c,v 1.16 93/08/25 09:08:33 sam Exp $
  47.  *
  48.  *    This program is offered without any warranty of any kind. It includes
  49.  *    no warranty of merchantability or fitness for any purpose. Testing and
  50.  *    suitability for any use are the sole responsibility of the user.
  51.  *
  52.  INFORMATION
  53.  *    Although there is no support offered with this program, the author will
  54.  *    endeavor to correct errors. Updates will also be made available from
  55.  *    time to time.
  56.  *
  57.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  58.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  59.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  60.  *
  61.  *    Also beginning in July 1990, this code will be archived at the
  62.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  63.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  64.  *    "public", system "bbs", and password "public".
  65.  *
  66.  *    This code is also available from the C Users Group in volume 317.
  67.  *
  68.  * END (from the original source)
  69.  */
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include "tiffcomp.h"
  73.  
  74. #ifndef TRUE
  75. #define    TRUE    1
  76. #define    FALSE    0
  77. #endif
  78.  
  79. #define WHITE    0
  80. #define BLACK    1
  81.  
  82. /*
  83.  * G3 2D and G4 decoding modes.  Note that
  84.  * the vertical modes are ordered so that
  85.  * (mode - MODE_VERT_V0) gives the vertical
  86.  * adjustment for the b1 parameter.
  87.  */
  88. #define MODE_NULL    0
  89. #define MODE_PASS    1
  90. #define MODE_HORIZ    2
  91. #define MODE_VERT_VL3    3
  92. #define MODE_VERT_VL2    4
  93. #define MODE_VERT_VL1    5
  94. #define MODE_VERT_V0    6
  95. #define MODE_VERT_VR1    7
  96. #define MODE_VERT_VR2    8
  97. #define MODE_VERT_VR3    9
  98. #define MODE_UNCOMP    10
  99. #define MODE_ERROR    11
  100. #define MODE_ERROR_1    12
  101.  
  102. unsigned long
  103. append_0(unsigned long prefix)
  104. {
  105.     return (prefix + (1L<<16));
  106. }
  107.  
  108. unsigned long
  109. append_1(unsigned long prefix)
  110. {
  111.     static unsigned short prefix_bit[16] = {
  112.     0x8000, 0x4000, 0x2000, 0x1000,
  113.     0x0800, 0x0400, 0x0200, 0x0100,
  114.     0x0080, 0x0040, 0x0020, 0x0010,
  115.     0x0008, 0x0004, 0x0002, 0x0001
  116.     };
  117.     unsigned char len = (prefix >> 16) & 0xf;
  118.     return (append_0(prefix) + prefix_bit[len]);
  119. }
  120.  
  121. #define    G3CODES
  122. #include "t4.h"
  123.  
  124. short
  125. search_table(unsigned long prefix, const tableentry* tab, int n)
  126. {
  127.     unsigned short len = (prefix >> 16) & 0xf;
  128.     unsigned short code = (prefix & 0xffff) >> (16 - len);
  129.  
  130.     while (n-- > 0) {
  131.     if (tab->length == len && tab->code == code)
  132.         return ((short) tab->runlen);
  133.     tab++;
  134.     }
  135.     return (G3CODE_INCOMP);
  136. }
  137.  
  138. #define    NCODES(a)    (sizeof (a) / sizeof (a[0]))
  139. short
  140. white_run_length(unsigned long prefix)
  141. {
  142.     return (search_table(prefix, TIFFFaxWhiteCodes, NCODES(TIFFFaxWhiteCodes)));
  143. }
  144.  
  145. short
  146. black_run_length(unsigned long prefix)
  147. {
  148.     return (search_table(prefix, TIFFFaxBlackCodes, NCODES(TIFFFaxBlackCodes)));
  149. }
  150. #undef NCODES
  151.  
  152. #define MAX_NULLPREFIX    200    /* max # of null-mode prefixes */
  153. typedef    unsigned char NullModeTable[MAX_NULLPREFIX][256];
  154. #define MAX_HORIZPREFIX    250    /* max # of incomplete 1-D prefixes */
  155. typedef    unsigned char HorizModeTable[MAX_HORIZPREFIX][256];
  156.  
  157.   /* the bit string corresponding to this row of the decoding table */
  158. long    null_mode_prefix[MAX_NULLPREFIX];
  159. NullModeTable null_mode;        /* MODE_*, indexed by bit and byte */
  160. NullModeTable null_mode_next_state;    /* next row of decoding tables to use */
  161.   /* number of prefixes or rows in the G4 decoding tables */
  162. short    null_mode_prefix_count = 0;
  163.  
  164. /*
  165.  * 2D uncompressed mode codes.  Note
  166.  * that two groups of codes are arranged
  167.  * so that the decoder can caluclate the
  168.  * length of the run by subtracting the
  169.  * code from a known base value.
  170.  */
  171. #define    UNCOMP_INCOMP    0
  172. /* runs of [0]*1 */
  173. #define    UNCOMP_RUN0    1
  174. #define    UNCOMP_RUN1    2
  175. #define    UNCOMP_RUN2    3
  176. #define    UNCOMP_RUN3    4
  177. #define    UNCOMP_RUN4    5
  178. #define    UNCOMP_RUN5    6
  179. #define    UNCOMP_RUN6    7
  180. /* runs of [0]* w/ terminating color */
  181. #define    UNCOMP_TRUN0    8
  182. #define    UNCOMP_TRUN1    9
  183. #define    UNCOMP_TRUN2    10
  184. #define    UNCOMP_TRUN3    11
  185. #define    UNCOMP_TRUN4    12
  186. /* special code for unexpected EOF */
  187. #define    UNCOMP_EOF    13
  188. /* invalid code encountered */
  189. #define    UNCOMP_INVALID    14
  190.  
  191. long    uncomp_mode_prefix[MAX_NULLPREFIX];
  192. NullModeTable uncomp_mode;
  193. NullModeTable uncomp_mode_next_state;
  194. short    uncomp_mode_prefix_count = 0;
  195.  
  196. /*
  197.  * Decoding action values for horiz_mode.
  198.  */
  199. #define ACT_INCOMP    0        /* incompletely decoded code */
  200. #define ACT_INVALID    1        /* invalide code */
  201. #define    ACT_WRUNT    2        /* terminating white run code */
  202. #define    ACT_WRUN    65        /* non-terminating white run code */
  203. #define    ACT_BRUNT    106        /* terminating black run code */
  204. #define    ACT_BRUN    169        /* non-terminating black run code */
  205. #define ACT_EOL        210        /* end-of-line code */
  206. HorizModeTable horiz_mode;
  207.  
  208. short
  209. horiz_mode_code_black(short runlen)
  210. {
  211.     return (runlen < 64 ? runlen + ACT_BRUNT : (runlen / 64) + ACT_BRUN);
  212. }
  213.  
  214. short
  215. horiz_mode_code_white(short runlen)
  216. {
  217.     return (runlen < 64 ? runlen + ACT_WRUNT : (runlen / 64) + ACT_WRUN);
  218. }
  219.  
  220. /*
  221.  * If the corresponding horiz_mode entry is ACT_INCOMP
  222.  * this entry is a row number for decoding the next byte;
  223.  * otherwise, it is the bit number with which to continue
  224.  * decoding the next codeword.
  225.  */
  226. HorizModeTable horiz_mode_next_state;
  227.         /* prefixes corresponding to the rows of the decoding table */
  228. long    horiz_mode_prefix[MAX_HORIZPREFIX];
  229.         /* color of next run, BLACK or WHITE */
  230. char    horiz_mode_color[MAX_HORIZPREFIX];
  231. short    horiz_mode_prefix_count = 0;
  232.  
  233. static    unsigned char bit_mask[8] =
  234.     { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  235.  
  236. void    build_null_mode_tables(void);
  237. short    find_horiz_mode_prefix(long, char);
  238. short    find_null_mode_prefix(long);
  239. short    null_mode_type(long);
  240. void    build_horiz_mode_tables(void);
  241. short    horiz_mode_code_black(short);
  242. short    horiz_mode_code_white(short);
  243. void    build_uncomp_mode_tables(void);
  244. void    write_tables(FILE*);
  245.  
  246. int    verbose = FALSE;
  247. char    *storage_class = "";
  248. int    packoutput = TRUE;
  249.  
  250. #ifdef __MWERKS__
  251. #include <console.h>
  252. #endif
  253.  
  254. void
  255. main(int argc, char** argv)
  256. {
  257. #ifdef __MWERKS__
  258.     argc = ccommand(&argv);
  259. #endif
  260.     while (argc > 1 && argv[1][0] == '-') {
  261.     if (strcmp(argv[1], "-v") == 0) {
  262.         verbose = TRUE;
  263.         argc--, argv++;
  264.     } else if (strcmp(argv[1], "-c") == 0) {
  265.         storage_class = "const ";
  266.         argc--, argv++;
  267.     } else if (strcmp(argv[1], "-p") == 0) {
  268.         packoutput = FALSE;
  269.         argc--, argv++;
  270.     }
  271.     }
  272.     build_null_mode_tables();        /* null mode decoding tables */
  273.     if (verbose) {
  274.     fprintf(stderr, "%d null mode prefixes defined\n",
  275.         (int) null_mode_prefix_count);
  276.     fprintf(stderr, "building uncompressed mode scripts...\n");
  277.     }
  278.     build_uncomp_mode_tables();        /* uncompressed mode decoding tables */
  279.     if (verbose) {
  280.     fprintf(stderr, "%d uncompressed mode prefixes defined\n",
  281.         (int) uncomp_mode_prefix_count);
  282.     fprintf(stderr, "building 1D scripts...\n");
  283.     }
  284.     build_horiz_mode_tables();        /* 1D decoding tables */
  285.     if (verbose)
  286.     fprintf(stderr, "%d incomplete prefixes defined\n",
  287.         (int) horiz_mode_prefix_count);
  288.     write_tables(stdout);
  289.     exit(0);
  290. }
  291.  
  292. void
  293. write_null_mode_table(FILE* fd, NullModeTable table, char* name)
  294. {
  295.     int i, j, lastNonZero;
  296.     char* outersep;
  297.     char* sep;
  298.  
  299.     fprintf(fd, "%su_char\t%s[%d][256] = {", storage_class,
  300.     name, (int) null_mode_prefix_count);
  301.     outersep = "";
  302.     if (!packoutput) {
  303.     for (i = 0; i < null_mode_prefix_count; i++) {
  304.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  305.         sep = "    ";
  306.         for (j = 0; j < 256; j++) {
  307.         fprintf(fd, "%s%2d", sep, (int) table[i][j]);
  308.         if (((j+1) % 16) == 0) {
  309.             fprintf(fd, ", /* %3d-%3d */\n", j-15, j);
  310.             sep = "    ";
  311.         } else
  312.             sep = ",";
  313.         }
  314.         fprintf(fd, "}");
  315.         outersep = ",";
  316.     }
  317.     } else {
  318.     for (i = 0; i < null_mode_prefix_count; i++) {
  319.         fprintf(fd, "%s{\n", outersep);
  320.         for (j = 255; j > 0; j--)
  321.         if (table[i][j] != 0)
  322.             break;
  323.         sep = "";
  324.         lastNonZero = j;
  325.         for (j = 0; j <= lastNonZero; j++) {
  326.         fprintf(fd, "%s%d", sep, (int) table[i][j]);
  327.         if (((j+1) % 24) == 0)
  328.             putc('\n', fd);
  329.         sep = ",";
  330.         }
  331.         fprintf(fd, "}");
  332.         outersep = ",";
  333.     }
  334.     }
  335.     fprintf(fd, "\n};\n");
  336. }
  337.  
  338. void
  339. write_horiz_mode_table(FILE* fd, HorizModeTable table, char* name)
  340. {
  341.     int i, j, lastNonZero;
  342.     char* outersep;
  343.     char* sep;
  344.  
  345.     fprintf(fd, "%s u_char\t%s[%d][256] = {", storage_class,
  346.     name, (int) horiz_mode_prefix_count);
  347.     outersep = "";
  348.     if (!packoutput) {
  349.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  350.         fprintf(fd, "%s\n/* prefix %d */ {\n", outersep, i);
  351.         sep = "    ";
  352.         for (j = 0; j < 256; j++) {
  353.         fprintf(fd, "%s%3d", sep, (int) table[i][j]);
  354.         if (((j+1) % 14) == 0) {
  355.             fprintf(fd, ", /* %3d-%3d */\n", j-13, j);
  356.             sep = "    ";
  357.         } else
  358.             sep = ",";
  359.         }
  360.         fprintf(fd, "\n}");
  361.         outersep = ",";
  362.     }
  363.     } else {
  364.     outersep = "";
  365.     for (i = 0; i < horiz_mode_prefix_count; i++) {
  366.         fprintf(fd, "%s{\n", outersep);
  367.         for (j = 255; j > 0; j--)
  368.         if (table[i][j] != 0)
  369.             break;
  370.         sep = "";
  371.         lastNonZero = j;
  372.         for (j = 0; j <= lastNonZero; j++) {
  373.         fprintf(fd, "%s%d", sep, (int) table[i][j]);
  374.         if (((j+1) % 24) == 0)
  375.             putc('\n', fd);
  376.         sep = ",";
  377.         }
  378.         fprintf(fd, "}");
  379.         outersep = ",";
  380.     }
  381.     }
  382.     fprintf(fd, "\n};\n");
  383. }
  384.  
  385. void
  386. write_define(FILE* fd, char* name, int value, char* comment)
  387. {
  388.     fprintf(fd, "#define\t%s\t%d", name, value);
  389.     if (!packoutput && comment)
  390.     fprintf(fd, "\t/* %s */", comment);
  391.     fprintf(fd, "\n");
  392. }
  393.  
  394. void
  395. write_preamble(FILE* fd)
  396. {
  397.     fprintf(fd, "%s\n",
  398. "/* DO NOT EDIT THIS FILE, IT WAS AUTOMATICALLY CREATED BY mkg3state */");
  399.     write_define(fd, "ACT_INCOMP", ACT_INCOMP, "incompletely decoded code");
  400.     write_define(fd, "ACT_INVALID", ACT_INVALID, "invalide code");
  401.     write_define(fd, "ACT_WRUNT", ACT_WRUNT, "terminating white run code");
  402.     write_define(fd, "ACT_WRUN", ACT_WRUN, "non-terminating white run code");
  403.     write_define(fd, "ACT_BRUNT", ACT_BRUNT, "terminating black run code");
  404.     write_define(fd, "ACT_BRUN", ACT_BRUN, "non-terminating black run code");
  405.     write_define(fd, "ACT_EOL", ACT_EOL, "end-of-line code");
  406.     fprintf(fd, "\n");
  407.     fprintf(fd, "/* modes that the decoder can be in */\n");
  408.     write_define(fd, "MODE_NULL", MODE_NULL, NULL);
  409.     write_define(fd, "MODE_PASS", MODE_PASS, NULL);
  410.     write_define(fd, "MODE_HORIZ", MODE_HORIZ, NULL);
  411.     write_define(fd, "MODE_VERT_V0", MODE_VERT_V0, NULL);
  412.     write_define(fd, "MODE_VERT_VR1", MODE_VERT_VR1, NULL);
  413.     write_define(fd, "MODE_VERT_VR2", MODE_VERT_VR2, NULL);
  414.     write_define(fd, "MODE_VERT_VR3", MODE_VERT_VR3, NULL);
  415.     write_define(fd, "MODE_VERT_VL1", MODE_VERT_VL1, NULL);
  416.     write_define(fd, "MODE_VERT_VL2", MODE_VERT_VL2, NULL);
  417.     write_define(fd, "MODE_VERT_VL3", MODE_VERT_VL3, NULL);
  418.     write_define(fd, "MODE_UNCOMP", MODE_UNCOMP, NULL);
  419.     write_define(fd, "MODE_ERROR", MODE_ERROR, NULL);
  420.     write_define(fd, "MODE_ERROR_1", MODE_ERROR_1, NULL);
  421.     fprintf(fd, "\n");
  422.     fprintf(fd, "#define\tRUNLENGTH(ix)    (TIFFFaxWhiteCodes[ix].runlen)\n");
  423.     fprintf(fd, "\n");
  424.     write_define(fd, "UNCOMP_INCOMP", UNCOMP_INCOMP, NULL);
  425.     fprintf(fd, "/* runs of [0]*1 */\n");
  426.     write_define(fd, "UNCOMP_RUN0", UNCOMP_RUN0, NULL);
  427.     write_define(fd, "UNCOMP_RUN1", UNCOMP_RUN1, NULL);
  428.     write_define(fd, "UNCOMP_RUN2", UNCOMP_RUN2, NULL);
  429.     write_define(fd, "UNCOMP_RUN3", UNCOMP_RUN3, NULL);
  430.     write_define(fd, "UNCOMP_RUN4", UNCOMP_RUN4, NULL);
  431.     write_define(fd, "UNCOMP_RUN5", UNCOMP_RUN5, NULL);
  432.     write_define(fd, "UNCOMP_RUN6", UNCOMP_RUN6, NULL);
  433.     fprintf(fd, "/* runs of [0]* w/ terminating color */\n");
  434.     write_define(fd, "UNCOMP_TRUN0", UNCOMP_TRUN0, NULL);
  435.     write_define(fd, "UNCOMP_TRUN1", UNCOMP_TRUN1, NULL);
  436.     write_define(fd, "UNCOMP_TRUN2", UNCOMP_TRUN2, NULL);
  437.     write_define(fd, "UNCOMP_TRUN3", UNCOMP_TRUN3, NULL);
  438.     write_define(fd, "UNCOMP_TRUN4", UNCOMP_TRUN4, NULL);
  439.     fprintf(fd, "/* special code for unexpected EOF */\n");
  440.     write_define(fd, "UNCOMP_EOF", UNCOMP_EOF, NULL);
  441.     fprintf(fd, "/* invalid code encountered */\n");
  442.     write_define(fd, "UNCOMP_INVALID", UNCOMP_INVALID, NULL);
  443.     fprintf(fd, "/* codes >= terminate uncompress mode */\n");
  444.     fprintf(fd, "#define\tUNCOMP_EXIT    UNCOMP_TRUN0\n");
  445.     fprintf(fd, "\n");
  446. }
  447.  
  448. void
  449. extern_table(FILE* fd, char* name)
  450. {
  451.     fprintf(fd, "extern\t%su_char %s[][256];\n", storage_class, name);
  452. }
  453.  
  454. void
  455. write_tables(FILE* fd)
  456. {
  457.     write_preamble(fd);
  458.     fprintf(fd, "#ifdef G3STATES\n");
  459.     write_null_mode_table(fd, null_mode, "TIFFFax2DMode");
  460.     write_null_mode_table(fd, null_mode_next_state, "TIFFFax2DNextState");
  461.     write_null_mode_table(fd, uncomp_mode, "TIFFFaxUncompAction");
  462.     write_null_mode_table(fd, uncomp_mode_next_state, "TIFFFaxUncompNextState");
  463.     write_horiz_mode_table(fd, horiz_mode, "TIFFFax1DAction");
  464.     write_horiz_mode_table(fd, horiz_mode_next_state, "TIFFFax1DNextState");
  465.     fprintf(fd, "#else\n");
  466.     extern_table(fd, "TIFFFax2DMode");
  467.     extern_table(fd, "TIFFFax2DNextState");
  468.     extern_table(fd, "TIFFFaxUncompAction");
  469.     extern_table(fd, "TIFFFaxUncompNextState");
  470.     extern_table(fd, "TIFFFax1DAction");
  471.     extern_table(fd, "TIFFFax1DNextState");
  472.     fprintf(fd, "#endif\n");
  473. }
  474.  
  475. short
  476. find_null_mode_prefix(long prefix)
  477. {
  478.     short j1;
  479.  
  480.     if (prefix == 0L)
  481.     return (0);
  482.     for (j1 = 8; j1 < null_mode_prefix_count; j1++)
  483.     if (prefix == null_mode_prefix[j1])
  484.         return (j1);
  485.     if (null_mode_prefix_count == MAX_NULLPREFIX) {
  486.     fprintf(stderr, "ERROR: null mode prefix table overflow\n");
  487.     exit(1);
  488.     }
  489.     if (verbose)
  490.     fprintf(stderr, "adding null mode prefix[%d] 0x%lx\n",
  491.         (int) null_mode_prefix_count, prefix);
  492.     null_mode_prefix[null_mode_prefix_count++] = prefix;
  493.     return (null_mode_prefix_count-1);
  494. }
  495.  
  496. short
  497. find_horiz_mode_prefix(long prefix, char color)
  498. {
  499.     short j1;
  500.  
  501.     for (j1 = 0; j1 < horiz_mode_prefix_count; j1++)
  502.     if (prefix == horiz_mode_prefix[j1] && horiz_mode_color[j1] == color)
  503.         return (j1);
  504.     /*
  505.      * It wasn't found, so add it to the tables, but first, is there room?
  506.      */
  507.     if (horiz_mode_prefix_count == MAX_HORIZPREFIX) {
  508.     fprintf(stderr, "ERROR: 1D prefix table overflow\n");
  509.     exit(1);
  510.     }
  511.     /* OK, there's room... */
  512.     if (verbose)
  513.     fprintf(stderr, "\nhoriz mode prefix %d, color %c = 0x%lx ",
  514.         (int) horiz_mode_prefix_count, "WB"[color], prefix);
  515.     horiz_mode_prefix[horiz_mode_prefix_count] = prefix;
  516.     horiz_mode_color[horiz_mode_prefix_count] = color;
  517.     horiz_mode_prefix_count++;
  518.     return (horiz_mode_prefix_count - 1);
  519. }
  520.  
  521. short
  522. find_uncomp_mode_prefix(long prefix)
  523. {
  524.     short j1;
  525.  
  526.     if (prefix == 0L)
  527.     return (0);
  528.     for (j1 = 8; j1 < uncomp_mode_prefix_count; j1++)
  529.     if (prefix == uncomp_mode_prefix[j1])
  530.         return (j1);
  531.     if (uncomp_mode_prefix_count == MAX_NULLPREFIX) {
  532.     fprintf(stderr, "ERROR: uncomp mode prefix table overflow\n");
  533.     exit(1);
  534.     }
  535.     if (verbose)
  536.     fprintf(stderr, "adding uncomp mode prefix[%d] 0x%lx\n",
  537.         (int) uncomp_mode_prefix_count, prefix);
  538.     uncomp_mode_prefix[uncomp_mode_prefix_count++] = prefix;
  539.     return (uncomp_mode_prefix_count-1);
  540. }
  541.  
  542. short
  543. null_mode_type(long prefix)
  544. {
  545.     switch (prefix) {
  546.     case 0x18000L: return (MODE_VERT_V0);    /* 1 */
  547.     case 0x36000L: return (MODE_VERT_VR1);    /* 011 */
  548.     case 0x34000L: return (MODE_VERT_VL1);    /* 010 */
  549.     case 0x32000L: return (MODE_HORIZ);        /* 001 */
  550.     case 0x41000L: return (MODE_PASS);        /* 0001 */
  551.     case 0x60C00L: return (MODE_VERT_VR2);    /* 0000 11 */
  552.     case 0x60800L: return (MODE_VERT_VL2);    /* 0000 10 */
  553.     case 0x70600L: return (MODE_VERT_VR3);    /* 0000 011 */
  554.     case 0x70400L: return (MODE_VERT_VL3);    /* 0000 010 */
  555.     case 0x80200L: return (MODE_ERROR);        /* 0000 0010 */
  556.     case 0x90300L: return (MODE_ERROR);        /* 0000 0011 0 */
  557.     case 0xA0380L: return (MODE_ERROR);        /* 0000 0011 10 */
  558.     case 0xA03C0L: return (MODE_UNCOMP);    /* 0000 0011 11 */
  559.     /*
  560.      * Under the assumption that there are no
  561.      * errors in the file, then this bit string
  562.      * can only be the beginning of an EOL code.
  563.      */
  564.     case 0x70000L: return (MODE_ERROR_1);    /* 0000 000 */
  565.     }
  566.     return (-1);
  567. }
  568.  
  569. short
  570. uncomp_mode_type(long prefix)
  571. {
  572.     short code;
  573.     short len;
  574.     switch (prefix) {
  575.     case 0x18000L: return (UNCOMP_RUN1);    /* 1 */
  576.     case 0x24000L: return (UNCOMP_RUN2);    /* 01 */
  577.     case 0x32000L: return (UNCOMP_RUN3);    /* 001 */
  578.     case 0x41000L: return (UNCOMP_RUN4);    /* 0001 */
  579.     case 0x50800L: return (UNCOMP_RUN5);    /* 0000 1 */
  580.     case 0x60400L: return (UNCOMP_RUN6);    /* 0000 01 */
  581.     case 0x70200L: return (UNCOMP_TRUN0);    /* 0000 001 */
  582.     case 0x80100L: return (UNCOMP_TRUN1);    /* 0000 0001 */
  583.     case 0x90080L: return (UNCOMP_TRUN2);    /* 0000 0000 1 */
  584.     case 0xA0040L: return (UNCOMP_TRUN3);    /* 0000 0000 01 */
  585.     case 0xB0020L: return (UNCOMP_TRUN4);    /* 0000 0000 001 */
  586.     }
  587.     code = prefix & 0xffffL;
  588.     len = (prefix >> 16) & 0xf;
  589.     return ((code || len > 10) ? UNCOMP_INVALID : -1);
  590. }
  591.  
  592. #define    BASESTATE(b)    ((unsigned char) ((b) & 0x7))
  593.  
  594. void
  595. build_null_mode_tables(void)
  596. {
  597.     short prefix;
  598.  
  599.     /*
  600.      * Note: the first eight entries correspond to
  601.      * a null prefix and starting bit numbers 0-7.
  602.      */
  603.     null_mode_prefix_count = 8;
  604.     for (prefix = 0; prefix < null_mode_prefix_count; prefix++) {
  605.     short byte;
  606.     for (byte = 0; byte < 256; byte++) {
  607.         short firstbit;
  608.         short bit;
  609.         long curprefix;
  610.         char found_code = FALSE;
  611.  
  612.         if (prefix < 8) {
  613.         curprefix = 0L;
  614.         firstbit = prefix;
  615.         } else {
  616.         curprefix = null_mode_prefix[prefix];
  617.         firstbit = 0;
  618.         }
  619.         for (bit = firstbit; bit < 8 && !found_code; bit++) {
  620.         short mode;
  621.  
  622.         if (bit_mask[bit] & byte)
  623.             curprefix = append_1(curprefix);
  624.         else
  625.             curprefix = append_0(curprefix);
  626.         switch (mode = null_mode_type(curprefix)) {
  627.         case MODE_PASS:
  628.         case MODE_HORIZ:
  629.         case MODE_VERT_V0:
  630.         case MODE_VERT_VR1:
  631.         case MODE_VERT_VR2:
  632.         case MODE_VERT_VR3:
  633.         case MODE_VERT_VL1:
  634.         case MODE_VERT_VL2:
  635.         case MODE_VERT_VL3:
  636.         case MODE_UNCOMP:
  637.         case MODE_ERROR:
  638.         case MODE_ERROR_1:
  639.             /*
  640.              * NOTE: if the bit number is 8, then the table
  641.              * entry will be zero, which indicates a new byte
  642.              * is to be fetched during the decoding process
  643.              */
  644.             found_code = TRUE;
  645.             null_mode[prefix][byte] = (unsigned char) mode;
  646.             null_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  647.             break;
  648.         }
  649.         }
  650.         if (!found_code) {
  651.         null_mode_next_state[prefix][byte] = (unsigned char)
  652.             find_null_mode_prefix(curprefix);
  653.         /*
  654.          * This indicates to the decoder that
  655.          * no valid code has yet been identified.
  656.          */
  657.         null_mode[prefix][byte] = MODE_NULL;
  658.         }
  659.     }
  660.     }
  661. }
  662.  
  663. void
  664. build_horiz_mode_tables(void)
  665. {
  666.     unsigned short byte;
  667.     short prefix;
  668.  
  669.     /*
  670.      * The first 8 are for white,
  671.      * the second 8 are for black,
  672.      * beginning with bits 0-7.
  673.      */
  674.     horiz_mode_prefix_count = 16;
  675.     for (prefix = 0; prefix < horiz_mode_prefix_count; prefix++)
  676.     for (byte = 0; byte < 256; byte++) {
  677.         short bits_digested = 0;
  678.         short bit;
  679.         short firstbit;
  680.         char color;
  681.         unsigned long curprefix;
  682.  
  683.         if (prefix < 8) {
  684.         color = WHITE;
  685.         curprefix = 0L;
  686.         firstbit = prefix;
  687.         } else if (prefix < 16) {
  688.         color = BLACK;
  689.         curprefix = 0L;
  690.         firstbit = prefix - 8;
  691.         } else {
  692.         color = horiz_mode_color[prefix];
  693.         curprefix = horiz_mode_prefix[prefix];
  694.         firstbit = 0;
  695.         }
  696.         for (bit = firstbit; bit < 8 && !bits_digested; bit++) {
  697.         if (bit_mask[bit] & byte)
  698.             curprefix = append_1(curprefix);
  699.         else
  700.             curprefix = append_0(curprefix);
  701.         /*
  702.          * The following conversion allows for arbitrary strings of
  703.          * zeroes to precede the end-of-line code 0000 0000 0001.
  704.          * It assumes no errors in the data, and is based on
  705.          * the assumption that the code replaced (12 consecutive
  706.          * zeroes) can only be "legally" encountered before the
  707.          * end-of-line code.  This assumption is valid only for
  708.          * a Group 3 image; the combination will never occur
  709.          * in horizontal mode in a proper Group 4 image.
  710.          */
  711.         if (curprefix == 0xC0000L)
  712.             curprefix = 0xB0000L;
  713.         if (color == WHITE) {
  714.             short runlength = white_run_length(curprefix);
  715.  
  716.             if (runlength == G3CODE_INVALID) {
  717.             horiz_mode[prefix][byte] = (unsigned char) ACT_INVALID;
  718.             horiz_mode_next_state[prefix][byte] = (unsigned char) bit;
  719.             bits_digested = bit + 1;
  720.             } else if (runlength == G3CODE_EOL) { /* Group 3 only */
  721.             horiz_mode[prefix][byte] = (unsigned char) ACT_EOL;
  722.             horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  723.             bits_digested = bit + 1;
  724.             } else if (runlength != G3CODE_INCOMP) {
  725.             horiz_mode[prefix][byte] = (unsigned char)
  726.                 horiz_mode_code_white(runlength);
  727.             horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  728.             bits_digested = bit + 1;
  729.             }
  730.         } else {        /* color == BLACK */
  731.             short runlength = black_run_length(curprefix);
  732.  
  733.             if (runlength == G3CODE_INVALID) {
  734.             horiz_mode[prefix][byte] = (unsigned char) ACT_INVALID;
  735.             horiz_mode_next_state[prefix][byte] = (unsigned char) (bit+8);
  736.             bits_digested = bit + 1;
  737.             } else if (runlength == G3CODE_EOL) { /* Group 3 only */
  738.             horiz_mode[prefix][byte] = (unsigned char) ACT_EOL;
  739.             horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  740.             bits_digested = bit + 1;
  741.             } else if (runlength != G3CODE_INCOMP) {
  742.             horiz_mode[prefix][byte] = (unsigned char)
  743.                 horiz_mode_code_black(runlength);
  744.             horiz_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  745.             bits_digested = bit + 1;
  746.             }
  747.         }
  748.         }
  749.         if (!bits_digested) {    /* no codewords after examining byte */
  750.         horiz_mode[prefix][byte] = (unsigned char) ACT_INCOMP;
  751.         horiz_mode_next_state[prefix][byte] = (unsigned char)
  752.             find_horiz_mode_prefix(curprefix, color);
  753.         }
  754.     }
  755. }
  756.  
  757. void
  758. build_uncomp_mode_tables(void)
  759. {
  760.     short prefix;
  761.  
  762.     /*
  763.      * Note: the first eight entries correspond to
  764.      * a null prefix and starting bit numbers 0-7.
  765.      */
  766.     uncomp_mode_prefix_count = 8;
  767.     for (prefix = 0; prefix < uncomp_mode_prefix_count; prefix++) {
  768.     short byte;
  769.     for (byte = 0; byte < 256; byte++) {
  770.         short firstbit;
  771.         short bit;
  772.         long curprefix;
  773.         char found_code = FALSE;
  774.  
  775.         if (prefix < 8) {
  776.         curprefix = 0L;
  777.         firstbit = prefix;
  778.         } else {
  779.         curprefix = uncomp_mode_prefix[prefix];
  780.         firstbit = 0;
  781.         }
  782.         for (bit = firstbit; bit < 8 && !found_code; bit++) {
  783.         short mode;
  784.  
  785.         if (bit_mask[bit] & byte)
  786.             curprefix = append_1(curprefix);
  787.         else
  788.             curprefix = append_0(curprefix);
  789.         mode = uncomp_mode_type(curprefix);
  790.         if (mode != -1) {
  791.             /*
  792.              * NOTE: if the bit number is 8, then the table
  793.              * entry will be zero, which indicates a new byte
  794.              * is to be fetched during the decoding process
  795.              */
  796.             found_code = TRUE;
  797.             uncomp_mode[prefix][byte] = (unsigned char) mode;
  798.             uncomp_mode_next_state[prefix][byte] = BASESTATE(bit+1);
  799.             break;
  800.         }
  801.         }
  802.         if (!found_code) {
  803.         uncomp_mode_next_state[prefix][byte] = (unsigned char)
  804.             find_uncomp_mode_prefix(curprefix);
  805.         /*
  806.          * This indicates to the decoder that
  807.          * no valid code has yet been identified.
  808.          */
  809.         uncomp_mode[prefix][byte] = UNCOMP_INCOMP;
  810.         }
  811.     }
  812.     }
  813. }
  814.